import { Controller } from "egg";
import { IndexCondition } from "../common";
import inputValidate from "../decorator/inputValidate";
import { createUserRules } from "../validatorRules/User";

export default class UserController extends Controller {
  public async index() {
    const { ctx } = this;
    const { pageIndex, pageSize, nikeName } = ctx.request.body;
    const _condition: IndexCondition = {
      select:
        "picture phoneNumber company department position nikeName createdAt id",
      ...(pageIndex && { pageIndex }),
      ...(pageSize && { pageSize }),
      ...(nikeName && { nikeName: { $regx: nikeName, $option: "i" } }),
      populate: [
        {
          path: "department",
          transform: (doc) => doc.department_name,
        },
        {
          path: "position",
          transform: (doc) => doc.position_name,
        },
      ],
    };
    const res = await ctx.service.user.findList(_condition);
    ctx.helper.success({ ctx, res });
  }

  @inputValidate(createUserRules, "userValidateFail")
  public async create() {
    const { ctx, service } = this;
    const { phoneNumber } = ctx.request.body;
    const data = await service.user.findByName({ phoneNumber });
    if (data) {
      return ctx.helper.error({ ctx, errorType: "commonAlreadyExists" });
    }
    const res = await service.user.add(ctx.request.body);
    ctx.helper.success({ ctx, res });
  }

  /**
   * 发送手机验证码
   */
  public async sendPhoneVeriCode() {
    const { ctx, app } = this;
    const { phoneNumber } = ctx.request.body;
    const phoneVeri = await app.redis.get(`phoneNumber-${phoneNumber}`);
    if (phoneVeri) {
      return ctx.helper.error({
        ctx,
        errorType: "sendVeriCodeFrequentlyFailInfo",
      });
    }
    // 生成四位数验证码
    const veriCode = Math.floor(Math.random() * 9000 + 1000).toString();
    try {
      // 发生手机验证码
      if (app.config.env === "prod") {
        const _resp = await ctx.service.user.sendSMS(phoneNumber, veriCode);
        if (_resp.body.code !== "OK") {
          return ctx.helper.error({ ctx, errorType: "sendVeriCodeError" });
        }
      }
      // 在redis中缓存验证码
      await app.redis.set(`phoneNumber-${phoneNumber}`, veriCode, "ex", 3000);
      // 返回验证码信息
      ctx.helper.success({
        ctx,
        res: app.config.env === "local" ? { veriCode } : { veriCode },
        msg: "验证码发送成功！",
      });
    } catch (e) {
      return ctx.helper.error({ ctx, errorType: "commonOperateFail" });
    }
  }

  /**
   * 验证手机验证码
   */
  public async verifyPhoneCode() {
    const { ctx, app } = this;
    const { phoneNumber, veriCode } = ctx.request.body;
    const preVeroCode = await app.redis.get(`phoneNumber-${phoneNumber}`);
    if (preVeroCode !== veriCode) {
      return ctx.helper.error({ ctx, errorType: "commonVeriCodeFailInfo" });
    }
    // 返回验证码信息
    ctx.helper.success({ ctx, msg: "验证码验证成功！" });
  }

  /**
   * 企业注册
   */
  public async orgRegister() {
    const { ctx, app } = this;
    const { phoneNumber, company_name } = ctx.request.body;
    const preVeroCode = await app.redis.get(`phoneNumber-${phoneNumber}`);
    if (!preVeroCode) {
      return ctx.helper.error({ ctx, errorType: "commonVeriCodeExpire" });
    }
    // 第一步：如果公司已存在，就不要添加公司
    const _company = await ctx.service.company.findByName(company_name);
    if (_company) {
      return ctx.helper.error({ ctx, errorType: "userCompanyExistsError" });
    }
    // 第二步：确定当前手机号是否存在，如果存在
    const _user = await ctx.service.user.findByName({
      phoneNumber,
    });
    if (_user) {
      return ctx.helper.error({ ctx, errorType: "userPhoneExistsError" });
    }
    // 第三步：公司和人绑定
    // > 1：确定默认的角色是否存在
    const _owner = await ctx.service.role.findByName("所有者");
    if (!_owner) {
      return ctx.helper.error({ ctx, errorType: "commonOperateFail" });
    }
    // > 2：注册公司
    const res = await ctx.service.user.orgRegister({
      ...ctx.request.body,
      role: _owner._id,
    });
    if (!res) {
      return ctx.helper.error({ ctx, errorType: "commonOperateFail" });
    }
    ctx.helper.success({ ctx, res, msg: "企业注册成功！" });
  }

  /**
   * 手机验证码登录
   */
  public async loginByCode() {
    const { ctx, app } = this;
    const { phoneNumber, veriCode } = ctx.request.body;
    const preVeroCode = await app.redis.get(`phoneNumber-${phoneNumber}`);
    if (preVeroCode !== veriCode) {
      return ctx.helper.error({ ctx, errorType: "commonVeriCodeFailInfo" });
    }
    const _user = await ctx.service.user.findByName({
      phoneNumber,
    });
    if (!_user) {
      return ctx.helper.error({ ctx, errorType: "userIsExistsError" });
    }
    const token = app.jwt.sign(
      {
        name: _user.nikeName,
        _id: _user._id,
        company: _user._id,
        role: _user.role,
      },
      app.config.jwt.secret,
      { expiresIn: "30day" }
    );
    ctx.helper.success({ ctx, res: { token }, msg: "登录成功！" });
  }

  /**
   * 密码登录
   */
  public async loginByPass() {
    const { ctx, app } = this;
    const { phoneNumber, password } = ctx.request.body;
    const _user = await ctx.service.user.findByName({
      phoneNumber,
    });
    if (!_user) {
      return ctx.helper.error({ ctx, errorType: "userIsExistsError" });
    }
    const verifyPwd = await ctx.compare(password, _user.password);
    if (!verifyPwd) {
      return ctx.helper.error({ ctx, errorType: "loginValidateFail" });
    }
    const token = app.jwt.sign(
      {
        name: _user.nikeName,
        _id: _user._id,
        company: _user._id,
        role: _user.role,
      },
      app.config.jwt.secret,
      { expiresIn: "30day" }
    );
    ctx.helper.success({ ctx, res: { token }, msg: "登录成功！" });
  }
}
